import { GenericEnvStore } from "@/modules/dev-env/store/generic-env-store.ts";
import type { LocalVersionItem, ToolInstallVersionItem } from "@/modules/dev-env/common/types.ts";
import path from "@/framework/util/path.ts";
import type { BaseEnvMirror } from "@/modules/dev-env/mirror/mirror.ts";
import { GolangGoDevCnMirror, GolangGoogleCnMirror } from "./golang-mirror.ts";
import { GolangAliyunMirror } from "./golang-aliyun-mirror.ts";
import type { UnzipCompleteArgs } from "@common/archives-file-types.ts";
import type { EnvVariableConfig } from "@/modules/dev-env/store/types.ts";
import semver from "semver";
import { EnvTree } from "@/modules/dev-env/common/tree.ts";

const pv = /[a-zA-Z]+/;

export class GolangEnvStore extends GenericEnvStore<GolangEnvStore> {
  constructor() {
    super("go");

    this.icon = "icon-golang-logo";
  }

  protected compareVersion(a: LocalVersionItem, b: LocalVersionItem): number {
    let av = a.version;
    let bv = b.version;
    // 测试版版本号上面有字母,从字母出截断给末尾加上补丁版本".0"来比较
    if (pv.test(av)) {
      const match = av.match(pv)?.[0];
      if (match) {
        av = av.substring(0, av.indexOf(match)) + ".0";
      }
    }
    if (pv.test(bv)) {
      const match = bv.match(pv)?.[0];
      if (match) {
        bv = bv.substring(0, bv.indexOf(match)) + ".0";
      }
    }
    const [majorA, minorA, patchA = "0"] = av.split(".");
    const [majorB, minorB, patchB = "0"] = bv.split(".");
    av = `${majorA}.${minorA}.${patchA}`;
    bv = `${majorB}.${minorB}.${patchB}`;
    return semver.compare(bv, av);
  }

  protected getVersionInfo(versionDir: string): Promise<LocalVersionItem | undefined> {
    return Promise.resolve({
      version: path.basename(versionDir),
      installPath: versionDir,
    });
  }

  protected getMirrors0(): BaseEnvMirror[] {
    return [new GolangAliyunMirror(), new GolangGoogleCnMirror(), new GolangGoDevCnMirror()];
  }

  async afterUnzipComplete(e: UnzipCompleteArgs, version: ToolInstallVersionItem) {
    // 解压后以版本号重命名目录
    const unzipDir = path.join(e.fileDir, "go");
    const versionDir = path.join(this.installDir, EnvTree.versionsDir, version.version);
    if (__DEV__) console.log(`[golang-env-store], rename ${unzipDir} -> ${versionDir}`);
    await native.fs.rename(unzipDir, versionDir);
  }

  getEnvVariables0(): EnvVariableConfig[] {
    return [
      {
        name: "GOPROXY",
        settable: true,
        showCurrent: true,
        options: [
          { value: "https://goproxy.cn" },
          { value: "https://mirrors.aliyun.com/goproxy/" },
          { value: "https://mirrors.huaweicloud.com/repository/goproxy/" },
          // ...
        ],
      },
      {
        name: "GO111MODULE",
        settable: true,
        showCurrent: true,
        options: [{ value: "auto" }, { value: "on" }, { value: "off" }],
      },
      {
        name: "GONOSUMDB",
        settable: true,
        showCurrent: true,
        options: [{ value: "*" }],
      },
      {
        name: "GOROOT",
        getValue: () => path.join(this.installDir, EnvTree.currentVersionDir),
        showCurrent: true,
        settable: true,
        readonly: true,
        help: "Golang安装根目录",
      },
      {
        name: "GOBIN",
        getValue: () => path.join("%GOROOT%", "bin"),
        showCurrent: true,
        settable: true,
      },
      {
        name: "GOPATH",
        showCurrent: true,
        settable: true,
      },
      {
        name: "PATH",
        getValue: () => path.join("%GOROOT%", "bin"),
        copyName: false,
        showCurrent: false,
        readonly: true,
        settable: false,
      },
    ];
  }
}
